<template>
  <div>
    <span>本地</span>
    <el-button @click="send">发送</el-button>
    <video :srcObject="localSrc" id="local" autoplay playsinline muted />
    <span>远端</span>
    <video :srcObject="remoteSrc" v-if="remoteSrc" id="remote" autoplay playsinline />
    <el-input id="text" v-model="message" /> <input type="file" @change="onFileChanged" />
    <el-button @click="send">发送</el-button>
    <el-button @click="createOffer">视频</el-button>
    <el-button @click="createAnswer">接视频</el-button>
    {{ msgList && msgList.data.length }}
    <div v-for="(item, index) in msgList.data" :key="index">
      <span v-if="item.isSelf"
        >我:

        <span v-if="!item.isImage">{{ item.msg }}</span>
        <img width="100" height="200" v-else :src="item.msg" alt="" />
      </span>
      <span v-else
        >其他人:
        <span v-if="!item.isImage">{{ item.msg }}</span>
        <img width="100" height="200" v-else :src="item.msg" alt="" />
      </span>
    </div>
  </div>
</template>

<script setup lang="ts">
import "webrtc-adapter"
import io from "socket.io-client"
// https://www.yoge.fun/rtc/events
const socket = io("http://127.0.0.1:3003/events")
const OfferSdp: any = ref(null)

socket.on("connect", function () {
  alert("Connected")
  socket.emit("joinRoom", "789456", (data: any) => {
    console.log(data, "data")
  })
})
socket.on("offer", async (offer: any) => {
  OfferSdp.value = offer
  console.log("拿到了offer", OfferSdp)
})
socket.on("answer", function (data: any) {
  console.log("响应了接视频")
  addAnswer(data.sdp)
})
socket.on("disconnect", function () {
  console.log("Disconnected")
})
const msgList: any = reactive({ data: [] })
const message: any = ref(null)
const localSrc: any = ref(null)
const remoteSrc: any = ref(null)
const pc = new RTCPeerConnection()
const watchMsg = () => {
  socket.on("chat", (data: any) => {
    msgList.data.push({
      isImage: data.isImage,
      msg: data.msg,
      isSelf: false
    })
    console.log("event", msgList.data)
  })
}

const send = () => {
  msgList.data.push({
    isImage: false,
    isSelf: true,
    msg: message.value
  })
  socket.emit("chat", message.value, (response: any) => console.log("Identity:", response, msgList))
}
const onFileChanged = (event: any) => {
  const file = event.target.files[0]
  const reader = new FileReader()
  reader.readAsArrayBuffer(file)
  reader.onload = (event) => {
    const fileInfo = {
      filename: file.name,
      mime: file.type,
      buffer: event?.target?.result,
      size: file.size
    }
    socket.emit("upload", fileInfo, (data: any) => {
      console.log(data)
    })
  }
}

// 初始化
async function init() {
  // // 获取本地端视频标签
  // const localVideo = document.getElementById("local") as HTMLVideoElement
  // // 获取远程端视频标签
  // const remoteVideo = document.getElementById("remote") as HTMLVideoElement

  // 采集本地媒体流
  const localStream = await navigator.mediaDevices.getUserMedia({
    video: true,
    audio: true
  })

  // 设置本地视频流
  localSrc.value = localStream
  console.log(localStream, "localStream")
  // 添加本地媒体流的轨道都添加到 RTCPeerConnection 中
  localStream.getTracks().forEach((track) => {
    pc.addTrack(track, localStream)
  })

  // 监听远程流，方法一：
  pc.ontrack = (event) => {
    console.log(event.streams, "event8888")
    remoteSrc.value = event.streams[0]
    console.log(remoteSrc.value, "remoteSrc")
  }
}

// 创建本地/远程 SDP 描述, 用于描述本地/远程的媒体流
let offerSdp = ""

const createOffer = async () => {
  // 创建 offer
  const offer = await pc.createOffer()
  // 设置本地描述
  await pc.setLocalDescription(offer)

  // 监听 RTCPeerConnection 的 onicecandidate 事件，当 ICE 服务器返回一个新的候选地址时，就会触发该事件
  pc.onicecandidate = async (event) => {
    if (event.candidate) {
      offerSdp = JSON.stringify(pc.localDescription)
      // 发送 offer
      if (offerSdp) {
        socket.emit("offer", {
          sdp: offerSdp
        })
      }
    }
  }
}
// offer to B ， B拿到后设置remote， 出发answer A 设置remote
//接视频
const createAnswer = async () => {
  const offer = OfferSdp
  // 解析字符串
  pc.onicecandidate = async (event) => {
    // Event that fires off when a new answer ICE candidate is created
    if (event.candidate) {
      socket.emit("answer", {
        sdp: JSON.stringify(pc.localDescription)
      })
    }
  }
  await pc.setRemoteDescription(JSON.parse(offer.value.sdp))
  const answer = await pc.createAnswer()
  await pc.setLocalDescription(answer)
}

// 添加 answer(应答)
const addAnswer = async (answerSdp: any) => {
  const answer = JSON.parse(answerSdp)
  if (!pc.currentRemoteDescription) {
    pc.setRemoteDescription(answer)
    socket.emit("answer", {
      sdp: JSON.stringify(pc.localDescription)
    })
  }
}
onBeforeUnmount(() => {
  socket.emit("leaveRoom", "789456", (data: any) => {
    console.log(data, "data")
  })
})
onMounted(() => {
  init()
  watchMsg()
})
</script>

<style></style>
